package com.aptemo.webetek.client.widgets.games;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.aptemo.webetek.client.WebetekUserServiceAsync;
import com.aptemo.webetek.client.commands.impl.GetEventsAction;
import com.aptemo.webetek.client.commands.impl.GetLabelsAction;
import com.aptemo.webetek.client.commands.responses.GotGameList;
import com.aptemo.webetek.client.commands.responses.GotLabelsList;
import com.aptemo.webetek.client.enums.EnumEventStatus;
import com.aptemo.webetek.client.enums.EnumUserRole;
import com.aptemo.webetek.client.events.AddBetEvent;
import com.aptemo.webetek.client.events.SelectedBetEvent;
import com.aptemo.webetek.client.exceptions.BackendException.EErrorCodes;
import com.aptemo.webetek.client.widgets.LoginProposalWidget;
import com.aptemo.webetek.client.widgets.paging.PagingController;
import com.aptemo.webetek.shared.EventBean;
import com.aptemo.webetek.shared.LabelBean;
import com.aptemo.webetek.shared.UserBean;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.ui.HasWidgets;

public class GamesPresenter
		extends PagingController<EventBean>
{

	private HandlerManager			meventBus;
	private WebetekUserServiceAsync	rpcService;
	private GamesDisplay			display;
	private int						pageNo		= 0;
	private String					teamId;
	private String					tagId;

	private ArrayList<EventBean>	gameList	= new ArrayList<EventBean>();
	protected ArrayList<LabelBean>	labels;

	private EnumEventStatus			status		= EnumEventStatus.ACTIVE;
	private HasWidgets				container;
	private UserBean				currentUser;

	public GamesPresenter(UserBean currentUser, GamesDisplay view, HandlerManager eventbus, WebetekUserServiceAsync rpc, String id, String tagId)
	{
		this(currentUser, view, eventbus, rpc, id, tagId, 0);
	}

	public GamesPresenter(UserBean currentUser, GamesDisplay view, HandlerManager eventBus, WebetekUserServiceAsync rpcService, String teamid, String tagId,
			int pageNo)
	{
		super(view.getPagingView(), 5);

		this.meventBus = eventBus;
		this.rpcService = rpcService;
		this.display = view;
		this.teamId = teamid;
		this.pageNo = pageNo;
		this.tagId = tagId;
		this.currentUser = currentUser;
	}

	private void bind()
	{
		// set default status
		display.setStatusValue(status);

		// loadPlayerDetails();
		// refresh handler...
		// meventBus.addHandler(BetPlacedEvent.TYPE, new RefreshEventHandler()
		// {
		//
		// @Override
		// public void onRefresh()
		// {
		// retrieveBetList();
		// }
		// });

		display.getStatusList().addChangeHandler(new ChangeHandler()
		{

			@Override
			public void onChange(ChangeEvent event)
			{
				renderList(gameList);
			}
		});

		display.getCreateGameBtn().addClickHandler(new ClickHandler()
		{

			@Override
			public void onClick(ClickEvent event)
			{
				meventBus.fireEvent(new AddBetEvent(teamId));
			}
		});

		display.getList().addClickHandler(new ClickHandler()
		{

			@Override
			public void onClick(ClickEvent event)
			{
				int selectedRow = display.getClickedRow(event);

				if (selectedRow >= 0)
				{
					// get it from paging...
					EventBean bet = getItem(selectedRow);
					String id = bet.getKey();
					meventBus.fireEvent(new SelectedBetEvent(id, teamId));
				}

			}
		});

		display.getLabels().addChangeHandler(new ChangeHandler()
		{

			@Override
			public void onChange(ChangeEvent event)
			{
				renderList(gameList);
			}
		});

	}

	private void retrieveBetList()
	{
		display.getInfoField().setText(display.translate("loading"));

		// Retrieve Bets from backend
		// 14 days ahead
		// Date betdatetreshold = new Date(System.currentTimeMillis() + 14 *
		// 86400 * 1000);
		// String value = display.getStatusFieldValue();
		// EnumBetStatus statusfilter = null;
		// if ((value != null) && (!value.isEmpty()))
		// {
		// statusfilter = EnumBetStatus.valueOf(value);
		// }
		// get 'em all
		GetEventsAction action = new GetEventsAction(teamId, tagId, null, null);
		rpcService.invoke(action, new GotGameList()
		{

			@Override
			public void onError(String message, EErrorCodes code)
			{
				if (code.equals(EErrorCodes.LOGIN_ERROR))
				{
					container.clear();
					container.add(new LoginProposalWidget());
				}
				else
				{
					display.getInfoField().setText(message);
				}
			}

			@Override
			public void got(ArrayList<EventBean> list)
			{

				// sort it
				Collections.sort(list);

				// save game list
				gameList = list;

				// display.getInfoField().setText("Bets list [" + list.size() +
				// "]");
				display.getInfoField().setText("");

				// load labels (asynch) and refresh list...
				loadLabels();

				// loadStakes4Team();

				if ((currentUser != null) && ((currentUser.getRole() == EnumUserRole.ADMIN) || (currentUser.getRole() == EnumUserRole.EDITOR)))
				{
					display.addAdminButtons();
					checkWarnings();
				}
			}

		});

	}

	// private void loadPlayerDetails()
	// {
	// //
	// GetPlayerDetailsAction action = new GetPlayerDetailsAction("", teamId);
	// rpcService.invoke(action, new GotAsynchCallback<UserBean>()
	// {
	//
	// @Override
	// public void onError(String message, EErrorCodes code)
	// {
	// // display.getInfoField().setText(message);
	// }
	//
	// @Override
	// public void onSuccess(UserBean result)
	// {
	// EnumRole role = result.getRole();
	// if ((role == EnumRole.ADMIN) || (role == EnumRole.EDITOR))
	// {
	// display.addAdminButtons();
	// checkWarnings();
	// }
	// }
	// });
	//
	// }

	protected void checkWarnings()
	{
		int waitcnt = 0;
		for (EventBean bet : gameList)
		{
			if (bet.getStatus() == EnumEventStatus.WAITINGRESULTS)
			{
				waitcnt++;
			}
		}
		if (waitcnt > 0)
		{
			display.getInfoField().setText("You have " + waitcnt + " waiting results...");
		}
	}

	// private void loadStakes4Team()
	// {
	// GetStakesAction action = new GetStakesAction(null);
	// action.setTeamKey(teamId);
	// rpcService.invoke(action, new GotStakeListResponse()
	// {
	//
	// @Override
	// public void got(ArrayList<StakeBean> list)
	// {
	// // renderList(list);
	// // display.setMyPicks(list);
	// // stakeList = list;
	// }
	//
	// @Override
	// public void onError(String message, EErrorCodes code)
	// {
	// // display.getInfoField().setText("Error getting stakes: " +
	// // message);
	// }
	//
	// });
	//
	// }

	private void renderList(ArrayList<EventBean> list)
	{
		List<EventBean> arr = new ArrayList<EventBean>();

		String selLabel = display.getSelectedLabelId();
		// String selStatus = display.getStatusFieldValue();
		EnumEventStatus selStatus = display.getStatusFieldValue();

		for (EventBean game : list)
		{
			String label = "";
			ArrayList<String> labels = game.getLabels();
			if (labels != null)
			{
				if (labels.size() > 0)
				{
					label = labels.get(0);
				}
			}
			// if (labelCheck(label, selLabel) && (statusCheck(game.getStatus(),
			// selStatus)))
			if (labelCheck(label, selLabel) && ((selStatus == null) || game.getStatus() == selStatus))
			{
				arr.add(game);
			}
		}

		setList(arr, pageNo);

	}

	private boolean labelCheck(String label, String sel)
	{
		return sel.isEmpty() /* || label.isEmpty() */|| (label.equals(sel)) ? true : false;
	}

	private boolean statusCheck(EnumEventStatus status, String sel)
	{
		return sel.isEmpty() || (status.toString().equals(sel)) ? true : false;
	}

	private void loadLabels()
	{
		GetLabelsAction ac = new GetLabelsAction(teamId);
		rpcService.invoke(ac, new GotLabelsList()
		{

			@Override
			public void onError(String message)
			{
				// TODO Auto-generated method stub
				display.getInfoField().setText("cannotLoadLabels");
			}

			@Override
			public void got(ArrayList<LabelBean> result)
			{
				labels = result;
				display.setLabels(result, tagId);
			}
		});

	}

	@Override
	public void go(HasWidgets container)
	{
		this.container = container;

		container.clear();
		container.add(display.getDisplay());

		bind();

		retrieveBetList();

	}

	@Override
	public void refreshPaging(List<EventBean> data)
	{
		display.updateBets(data, teamId, meventBus, rpcService);
	}

}
